/*
 * Copyright (C) 2022, KylinSoft Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 * Authors: iaom <zhangpengfei@kylinos.cn>
 *
 */
#include "status-change-shortcut.h"
#include <QDBusConnection>
#include <QDBusReply>
#include <QDebug>
#include <QDBusPendingCall>
#include <QDBusPendingReply>
#include <QApplication>
#include <QTranslator>

static const QString SERVICE = QStringLiteral("com.kylin.statusmanager.interface");
static const QString PATH = QStringLiteral("/");
static const QString INTERFACE = QStringLiteral("com.kylin.statusmanager.interface");
static const QString MODE_CHANGE_SIGNAL = QStringLiteral("mode_change_signal");
static const QString GET_TABLETMODE_METHOD = QStringLiteral("get_current_tabletmode");
static const QString SET_TABLETMODE_METHOD = QStringLiteral("set_tabletmode");
static const QString TABLETMODE_ICON = QStringLiteral("ukui-tablemode-symbolic");

using namespace UkuiShortcut;
StatusChangeShortcut::StatusChangeShortcut()
{
    initMetaData();
    m_statusManagerIface = new QDBusInterface(SERVICE, PATH, INTERFACE, QDBusConnection::sessionBus(), this);
    if(!m_statusManagerIface->isValid()) {
        qWarning() << "StatusChangeShortcut error:" << m_statusManagerIface->lastError();
        m_isEnable = false;
        return;
    }

    //We can't guarantee the stability of "kylin-status-manager", sou do it cautiously.
    QDBusPendingCall pcall = m_statusManagerIface->asyncCall(GET_TABLETMODE_METHOD);
    QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this);
    connect(watcher, &QDBusPendingCallWatcher::finished, [ & ](QDBusPendingCallWatcher *call = nullptr){
        QDBusPendingReply<bool> reply = *call;
        if (reply.isError()) {
            qWarning() << "StatusChangeShortcut error, call" << GET_TABLETMODE_METHOD << "failed!";
            m_isEnable = false;
            Q_EMIT enableStatusChanged(m_isEnable);
        } else {
            statusChangeSlot(reply.value());
            m_isEnable = true;
            Q_EMIT enableStatusChanged(m_isEnable);
        }
        call->deleteLater();
    });

    if(!QDBusConnection::sessionBus().connect(SERVICE, PATH, INTERFACE, MODE_CHANGE_SIGNAL, this, SLOT(statusChangeSlot(bool)))) {
        qWarning() << "StatusChangeShortcut error, connect " << MODE_CHANGE_SIGNAL << "failed!";
    }

    QTranslator *translator = new QTranslator(this);
    try {
        if(!translator->load(QString(TRANSLATION_FILE_DIR) + "/status-change-shortcut_" + QLocale::system().name() + ".qm")) throw -1;
        QApplication::installTranslator(translator);
    } catch(...) {
        qWarning() << "StatusChangeShortcut load translations file" << QLocale::system().name() << "failed!";
    }

    //set initial status info
    m_currentStatusInfo.setName(tr("Tablet Mode"));
    m_currentStatusInfo.setIcon(TABLETMODE_ICON);

    m_currentStatusInfo.setColor(Color::ColorRole::BaseColor);

}

StatusChangeShortcut::~StatusChangeShortcut()
{


}

QString StatusChangeShortcut::pluginId()
{
    return QStringLiteral("StatusChangeShortcut");
}

void StatusChangeShortcut::active(PluginMetaType::Action action)
{
    if(PluginMetaType::Action::Click == action) {
        m_statusManagerIface->asyncCall(SET_TABLETMODE_METHOD, !m_isTabletMode, "ukui-sidebar", "changemode");
    }
}

const StatusInfo StatusChangeShortcut::currentStatus()
{
    return m_currentStatusInfo;
}

bool StatusChangeShortcut::isEnable()
{
    return m_isEnable;
}

void StatusChangeShortcut::statusChangeSlot(bool isTabletMode)
{
    if(m_isTabletMode == isTabletMode)
        return;
    setStatusInfo(isTabletMode);
    Q_EMIT statusChanged(m_currentStatusInfo);          
}

void StatusChangeShortcut::setStatusInfo(bool isTabletMode)
{
    qDebug() << "StatusChangeShortcut::setStatusInfo" << isTabletMode;
    m_isTabletMode = isTabletMode;
    m_currentStatusInfo.setColor(isTabletMode ? Color::ColorRole::HighLight : Color::ColorRole::BaseColor);
}

QMap<PluginMetaType::SystemMode, PluginMetaData> StatusChangeShortcut::pluginMetaData()
{
    return m_metaData;
}

void StatusChangeShortcut::initMetaData()
{
    PluginMetaData pc {true, 0, PluginMetaType::PluginType::Icon};
    PluginMetaData tablet {true, 0, PluginMetaType::PluginType::Icon};
    m_metaData.insert(PluginMetaType::SystemMode::PC, pc);
    m_metaData.insert(PluginMetaType::SystemMode::Tablet, tablet);
}
